package cn.codergege.demo.okhttp

import cn.codergege.utils.doRedirect
import okhttp3.*
import org.jsoup.Jsoup
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import java.util.concurrent.ConcurrentHashMap
import java.util.ArrayList

@SpringBootTest
class LoginDemoTest {
    private val userAgent =
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"
    lateinit var client: OkHttpClient
    lateinit var clientAuto: OkHttpClient
    lateinit var gitee: String
    @BeforeEach
    fun setup() {
        gitee = "https://gitee.com"
        client = OkHttpClient().newBuilder()
            .followRedirects(false)
            .followSslRedirects(false)
            .cookieJar(object : CookieJar {
                // 存在内存
                private val storage = ConcurrentHashMap<String, List<Cookie>>()
                override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {
                    val host = url.host() // 有些地方可能用 host 管理 cookie 不行啊... 试试 oa
                    if (!cookies.isEmpty()) {
                        storage[host] = cookies
                    }
                }
                override fun loadForRequest(url: HttpUrl): List<Cookie> {
                    val host = url.host()
                    val list = storage[host]
                    // 注意, 这里不能返回空
                    return list ?: ArrayList<Cookie>()
                }
            }).build()
        println("In setup ......................")
        println(client)
        println("In setup ......................")
    }

    @Test
    fun testLogin() {
        val giteeLoginUrl = "${gitee}/login"
        // 构造需要的 post 参数
        // 获取 authenticity_token
        // <input name="authenticity_token" type="hidden" value="JqkYiAMuARudsW1Lo1BtcTndGq2DwY/3XMbsBBT6TG0=">
        // 构造 request 用于获取 token
        val request = Request.Builder()
            .addHeader("User-Agent", userAgent)
            .url(giteeLoginUrl)
            .build()
        var resp = client.newCall(request).execute()
        resp = doRedirect(client, resp, userAgent)
        // 然后获取 token
        val token = Jsoup.parse(resp?.body()?.string())
            .select("input[name='authenticity_token']")
            .attr("value")
        println("token -- $token")

        // 接下去构造 post 参数, 发送 post 请求模拟登陆
        val userName = "codergege@163.com"
        val password = "880322"
        val requestPost = Request.Builder()
            .url(giteeLoginUrl)
            .addHeader("User-Agent", userAgent)
            .post(FormBody.Builder()
                .addEncoded("utf8", "%E2%9C%93")
                .add("authenticity_token", token)
                .add("redirect_to_url", "")
                .add("user[login]", userName)
                .add("user[password]", password)
                .add("captcha", "")
                .add("user[remember_me]", "0")
                .add("commit", "登 录")
                .build()
            )
            .build()
        val loginResp = client.newCall(requestPost).execute()
        var loginedResp: Response? = doRedirect(client, loginResp, userAgent)
        // 处理返回页面
        println("----> " + loginedResp?.message())
        val doc = Jsoup.parse(loginedResp?.body()?.string())
        val stars = doc.select("#user-show-detail > div > div.five.wide.column > div.git-user-header > div > div.git-user-infodata > div.ui.grid > div:nth-child(2) > a > div").text().toInt()
        println("我的 stars 数是 $stars")
    }
}
